跳到主要内容

pyenv instruction

· 阅读需 5 分钟

What is pyenv?

pyenv is a Python version manager which is a tool to manage multiple Python versions.

pyenv-virtualenv is a tool to create isolated Python environments.

It allows pyenv and virtualenv to work together.

(pyenv-virtualenv 是一个可以将 pyenvvirtualenv 无缝连接起来的插件)[1]

Why use pyenv?

When you develop multiple python projects, and these projects depends on different versions of Python or different Python libraries, you need this pyenv tool to manage Python versions or pyenv-virtualenv to manage different isolated environments with pyenv.

(当你在开发多个 Python 项目,且这些项目依赖了不同版本的 Python 或者不同库时,就会需要 pyenv 来管理 Python 版本或者使用 pyenv-virtualenv 来管理不同独立的 Python 环境)

How it works?

Sample from https://github.com/pyenv/pyenv#how-it-works .

graph LR
cmd[Python-related command<br/>Like python, pip, ...] --> Shims
Shims --> pyenv

Simply to say, any Python-related command (like pip, python, pydoc...) will be executed by ~/.pyenv/shims/<command> first, then a proper Python version will be selected and the command will be executed

(简单来说,所有与 Python 相关的指令(比如 pip, python, pydoc...)都会被 ~/.pyenv/shims/<command> 执行,然后 pyenv 会选中一个合适的 Python 版本与环境来执行该指令).

Order of Python version selection

  1. check PYENV_VERSION environment variable (could be set by pyenv shell). If it is set, use it. Otherwise, go to step 2.
  2. check .python-version file in the current directory (could be set by pyenv local). If it is set, use it. Otherwise, go to step 3.
  3. check .python-version file in all of the parent directories. If it is found, use it. Otherwise, go to step 4(找当前目录的所有父目录,看是否有 .python-version 文件。如果找到则使用,否则,转进到第 4 步).
  4. check $(pyenv root)/version file. If it is set, use it. Otherwise, use the default version defined by system.

Installation

Sample from https://github.com/pyenv/pyenv#installation and https://github.com/pyenv/pyenv-virtualenv#installation .

For Linux/macOS

End-to-end installation commands at my environments:

ENV-LAPTOP: Homebrew at macOS with zsh:

brew update
brew install pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc # install `pyenv` into your shell as a shell function, enable shims and autocompletion
brew install pyenv-virtualenv
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.zshrc

ENV-WORK: Ubuntu 20.04 with zsh:

git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc # install `pyenv` into your shell as a shell function, enable shims and autocompletion
git clone https://github.com/pyenv/pyenv-virtualenv.git .pyenv/plugins/pyenv-virtualenv
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.zshrc

For Windows

pyenv does not support Windows yet. So I use pyenv-win instead.

Because pyenv is not supported at Windows, then pyenv-virtualenv is unavailable at Windows too. So I use virtualenv instead.

End-to-end installation commands at my environment:

ENV-PC: Windows 10 with PowerShell 7.2.1[4]:

git clone https://github.com/pyenv-win/pyenv-win.git "$HOME/.pyenv"
[System.Environment]::SetEnvironmentVariable('PYENV',$env:USERPROFILE + "\.pyenv\pyenv-win\","User")
[System.Environment]::SetEnvironmentVariable('PYENV_ROOT',$env:USERPROFILE + "\.pyenv\pyenv-win\","User")
[System.Environment]::SetEnvironmentVariable('PYENV_HOME',$env:USERPROFILE + "\.pyenv\pyenv-win\","User")
[System.Environment]::SetEnvironmentVariable('path', $env:USERPROFILE + "\.pyenv\pyenv-win\bin;" + $env:USERPROFILE + "\.pyenv\pyenv-win\shims;" + [System.Environment]::GetEnvironmentVariable('path', "User"),"User")

pyenv install <version>
pyenv global <version>
python -m pip install --user virtualenv

Usage

pyenv/pyenv-win

# check all installable Python versions
pyenv install --list
# install a specific Python version
pyenv install <version>
# use a specific Python version globally
pyenv global <version>
# use a specific Python version in current directory or in all of its subdirectories
pyenv local <version>
# use a specific Python version in the current shell
pyenv shell <version>

pyenv-virtualenv

pyenv virtualenv <version> <env_name>
pyenv activate <env_name>
pyenv deactivate
# delete venv
pyenv virtualenv-delete <env_name>

virtualenv

python -m venv <env_name>
source <env_name>/bin/activate # for unix-like systems
.\<env_name>\Scripts\activate # for Windows
deactivate
# delete venv
rm -rf <env_name>

Q & A

Q: Error occurred: ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Run commands below[2]:

sudo apt-get update
sudo apt-get install make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

Q: Error occurred: ImportError: libpython3.8.so.1.0: cannot open shared object file: No such file or directory

Run commands below[3]:

env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install x.x.x
ls ~/.pyenv/version/x.x.x/lib

Q: Erorr occurred: ModuleNotFoundError: No module named '_lzma'

Run commands below (MacOS):

brew install xz
pyenv uninstall <your_python_version>
pyenv install <your_python_version>

References